﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using CoreDC.Classes;
using Google.API.Translate;
using Google.API;


namespace CoreDC.Demo
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            cmbSendMethod.SelectedIndex = 0;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            cmbNickList.Items.Clear();

            myDcClient.ClientInfo.Description = txtDescription.Text;
            myDcClient.ClientInfo.Email = txtEmail.Text;
            myDcClient.ClientInfo.Username = txtUsername.Text;
            myDcClient.ClientInfo.Password = txtPassword.Text;

            if (rdbEmptyShare.Checked)
            {
                myDcClient.ClientInfo.Share = CoreDC.Classes.ClientInfo.Sharesize.Empty;
            }
            else if (rdbSmallShare.Checked)
            {
                myDcClient.ClientInfo.Share = CoreDC.Classes.ClientInfo.Sharesize.Small;
            }
            else if (rdbMediumShare.Checked)
            {
                myDcClient.ClientInfo.Share = CoreDC.Classes.ClientInfo.Sharesize.Medium;
            }
            else if (rdbLargeShare.Checked)
            {
                myDcClient.ClientInfo.Share = CoreDC.Classes.ClientInfo.Sharesize.Large;
            }

            myDcClient.ClientInfo.FollowRedirects = chkFollowRedirects.Checked;

            if (!String.IsNullOrEmpty(txtHubAddress.Text))
            {
                myDcClient.ClientInfo.Hostname = txtHubAddress.Text;
            }
            if (!String.IsNullOrEmpty(txtPort.Text))
            {
                myDcClient.ClientInfo.Port = Convert.ToInt32(txtPort.Text);
            }

            foreach (User user in myDcClient.NickList)
            {

            }

            myDcClient.Connect();
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            try
            {
                cmbNickList.Items.Clear();
                myDcClient.Disconnect();
            }
            catch { }
        }

        private void btnSendMainchatMessage_Click(object sender, EventArgs e)
        {
            switch ((string)cmbSendMethod.SelectedItem)
            {
                case "Main":
                    myDcClient.SendMainchatMessage(txtSendMainchatMessage.Text);
                    break;
                case "PM":
                    myDcClient.SendPrivateMessage(cmbNickList.Text, txtSendMainchatMessage.Text);
                    break;
                case "Raw":
                    myDcClient.SendRawMessage(txtSendMainchatMessage.Text);
                    break;
                default:
                    myDcClient.SendMainchatMessage(txtSendMainchatMessage.Text);
                    break;
            }
        }

        private void cmbEventChooser_SelectedIndexChanged(object sender, EventArgs e)
        {
            rtxtDisplay1.Visible = false;
            rtxtDisplay2.Visible = false;
            rtxtDisplay3.Visible = false;
            rtxtDisplay4.Visible = false;
            rtxtDisplay5.Visible = false;
            rtxtDisplay6.Visible = false;
            lstDisplay1.Visible = false;
            lstTTHSearch.Visible = false;
            btnFindIPs.Visible = false;
            lstFindIPs.Visible = false;

            switch ((string)cmbEventChooser.SelectedItem)
            {
                case "OnMainchatMessage":
                    rtxtDisplay1.Visible = true;
                    break;
                case "OnPrivateMessageRecieved":
                    rtxtDisplay2.Visible = true;
                    break;
                case "OnPrivateMessageSent":
                    rtxtDisplay3.Visible = true;
                    break;
                case "OnMessageReceived":
                    rtxtDisplay4.Visible = true;
                    break;
                case "OnMessageSent":
                    rtxtDisplay5.Visible = true;
                    break;
                case "OnSearch":
                    lstDisplay1.Visible = true;
                    break;
                case "OnTTHSearch":
                    lstTTHSearch.Visible = true;
                    break;
                case "OnConnectToMe":
                    btnFindIPs.Visible = true;
                    lstFindIPs.Visible = true;
                    break;
                default:
                    break;
            }
        }

        private void myDcClient_OnMainchatMessage(DcClient sender, CoreDC.Classes.User user, string text, bool ownMessage)
        {
            rtxtDisplay1.AppendText("<" + user.Username + "> " + text);
            rtxtDisplay1.AppendText(Environment.NewLine);
            if (!ownMessage)
            {
                DemoTranslator(true, user, text);
            }
        }

        private void myDcClient_OnPrivateMessageRecieved(DcClient sender, CoreDC.Classes.User user, string text)
        {
            rtxtDisplay2.AppendText("<" + user.Username + "> " + text);
            rtxtDisplay2.AppendText(Environment.NewLine);
            //sender.SendPrivateMessage(user, "I am a CoreDC Demobot!!1 - Visit http://coredc.googlecode.com for more information.");
            if (user.Username != myDcClient.ClientInfo.Username)
            {
                DemoTranslator(false, user, text);
            }
        }

        private void myDcClient_OnPrivateMessageSent(DcClient sender, CoreDC.Classes.User user, string text)
        {
            rtxtDisplay3.AppendText("Sent to " + user.Username + ":"+ Environment.NewLine);
            rtxtDisplay3.AppendText("<" + myDcClient.ClientInfo.Username + "> " + text);
            rtxtDisplay3.AppendText(Environment.NewLine);
        }

        /// <summary>
        /// Demo for making a translatorbot
        /// </summary>
        /// <param name="mainchat">Display in mainchat</param>
        /// <param name="user">User who asked for translation</param>
        /// <param name="message">The message</param>
        private void DemoTranslator(bool mainchat, User user, string message)
        {
            // translate > hej på dig
            // translated > [from swedish] Hello

            // translate from swedish > hej på dig
            // translated > Hello

            // translate to swedish > hiya how are you
            // translated > [from swedish] Hej hur mår du

            // translate from swedish to english > Hej på dig
            // translated > Hello

            // translate list languages
            // translated > English, Swedish, Japanese, ..

            if (message.StartsWith("translate"))
            {
                var response = string.Empty;
                var divider = message.IndexOf(">");
                if (divider > -1)
                {
                    var cmd = message.Substring(0, divider);
                    var text = message.Substring(divider + 1).Trim();

                    var list = cmd.Contains("list languages");

                    if (!list)
                    {
                        var langFrom = "";
                        var langTo = "";

                        // get translate from language
                        if (cmd.Contains("from "))
                        {
                            try
                            {
                                var first = cmd.IndexOf("from ") + 5;
                                var second = cmd.IndexOf(" ", first);
                                langFrom = cmd.Substring(first, second - first);
                            }
                            catch { }
                        }

                        // get translate to language
                        if (cmd.Contains("to "))
                        {
                            try
                            {
                                var first = cmd.IndexOf("to ") + 3;
                                var second = cmd.IndexOf(" ", first);
                                langTo = cmd.Substring(first, second - first);
                            }
                            catch { }
                        }

                        // Set languages to convert from and to
                        var from = Language.Unknown;
                        var to = Language.English;

                        // Try to parse user input
                        if (!string.IsNullOrEmpty(langFrom))
                        {
                            try
                            {
                                from = (Language)Enum.Parse(typeof(Language), langFrom, true);
                            }
                            catch { }
                        }

                        // Try to parse user input
                        if (!string.IsNullOrEmpty(langTo))
                        {
                            try
                            {
                                to = (Language)Enum.Parse(typeof(Language), langTo, true);
                            }
                            catch { }
                        }

                        // Try to translate
                        try
                        {
                            if (from == Language.Unknown)
                            {
                                response = Translator.TranslateAndDetect(text, to, out from);
                                response = "[from " + from.ToString() + "] " + response;
                            }
                            else
                            {
                                response = Translator.Translate(text, from, to);
                            }
                        }
                        catch (Exception e)
                        {
                            response = e.Message;
                        }
                    }
                    else
                    {
                        // List languages that are translatable
                        StringBuilder langList = new StringBuilder();

                        foreach (string s in Enum.GetNames(typeof(Language)))
                        {
                            langList.Append(s + ", ");
                        }
                        response = langList.Remove(langList.Length - 2, 2).ToString();
                    }

                    // Send back the response
                    if (!string.IsNullOrEmpty(response))
                    {
                        if (mainchat)
                        {
                            myDcClient.SendMainchatMessage("translated > " + response);
                        }
                        else
                        {
                            myDcClient.SendPrivateMessage(user, "translated > " + response);
                        }
                    }
                }
            }
        }

        private void myDcClient_OnMessageReceived(DcClient sender, string text)
        {
            rtxtDisplay4.AppendText("[" + DateTime.Now.ToLongTimeString() + "] " + text);
            rtxtDisplay4.AppendText(Environment.NewLine);

            try 
            {
                WriteToFile(text, text.Substring(0, text.IndexOf(" ")) + ".txt");
            } 
            catch
            {
            }
        }

        private void myDcClient_OnMessageSent(DcClient sender, string text)
        {
            string[] messages = text.Split("|".ToCharArray());
            foreach (string message in messages)
            {
                if (message.Length > 1)
                {
                    rtxtDisplay5.AppendText("[" + DateTime.Now.ToLongTimeString() + "] " + message);
                    rtxtDisplay5.AppendText(Environment.NewLine);
                }
            }
        }

        private void myDcClient_OnSearch(DcClient sender, CoreDC.Classes.SearchInfo searchInfo)
        {
            ListViewItem it = new ListViewItem();

            it.Text = searchInfo.User.Username;
            if (searchInfo.User.IP != null && !searchInfo.User.IP.Equals(new IPAddress(0)))
            {
                it.SubItems.Add(searchInfo.User.IP.ToString());
            }
            else
            {
                it.SubItems.Add("");
            }
            it.SubItems.Add(searchInfo.DataType.ToString());
            it.SubItems.Add(searchInfo.SearchPattern);

            if (searchInfo.IsTTH)
            {
                lstTTHSearch.Items.Add(it);
            }
            else
            {
                lstDisplay1.Items.Add(it);
            }
        }

        private void WriteToFile(string text, string path)
        {
            if (chkActivateLogging.Checked)
            {
                StreamWriter sw = new StreamWriter(path, true);
                sw.Write(text + Environment.NewLine);
                sw.Close();
            }
        }

        bool waitingForInfo = false;
        List<User> orgList = new List<User>();
        User testUser = new User();

        private void FindUsersIPs()
        {
            CreateIpTestUserList(false);
            TestForIP();
        }
        
        private void CreateIpTestUserList(bool passiveUsers)
        {
            foreach (var user in myDcClient.NickList)
            {
                if (user.IP.Equals(new IPAddress(0)))
                {
                    // We don't have an IP for the user, let's try to find it
                    if (!user.IsOperator && user.Username != myDcClient.ClientInfo.Username)
                    {
                        var test = (passiveUsers) ? true : user.Description.Contains("M:A");
                        if (test)
                            orgList.Add(user.Clone());
                    }
                }
                else
                {
                    // We already have an IP for the user
                    var item = new ListViewItem();
                    item.Text = user.Username;
                    item.SubItems.Add(user.IP.ToString());
                    item.SubItems.Add(user.Port.ToString());

                    lstFindIPs.Items.Add(item);
                }
            }
        }

        private void TestForIP()
        {
            if (!waitingForInfo && orgList.Count > 0)
            {
                testUser = orgList[0];
                orgList.Remove(testUser);

                waitingForInfo = true;
                myDcClient.SendRevConnectToMe(testUser);

                // In case we don't get a connecttome in a certain time, move on
                myTimer.Interval = 15000;
                myTimer.Enabled = true;
                myTimer.Start();
            }

            if (orgList.Count == 0)
            {
                myTimer.Stop();
                myTimer.Enabled = false;
            }
        }

        private void myDcClient_OnClientConnectionRecieved(DcClient sender, User user)
        {
            if (waitingForInfo)
            {
                testUser.IP = user.IP;
                testUser.Port = user.Port;

                myDcClient.NickList[testUser.Username].IP = user.IP;
                myDcClient.NickList[testUser.Username].Port = user.Port;

                var item = new ListViewItem();
                item.Text = testUser.Username;
                item.SubItems.Add(testUser.IP.ToString());
                item.SubItems.Add(testUser.Port.ToString());
                lstFindIPs.Items.Add(item);

                waitingForInfo = false;

                TestForIP();
            }
        }

        private void btnFindIPs_Click(object sender, EventArgs e)
        {
            FindUsersIPs();
        }

        private void myTimer_Tick(object sender, EventArgs e)
        {
            waitingForInfo = false;
            TestForIP();
        }

        private void myDcClient_OnJoin(DcClient sender, User user)
        {
            var username = user.Username;

            if (!cmbNickList.Items.Contains(username))
            {
                cmbNickList.Items.Add(username);
            }
        }

        private void myDcClient_OnParts(DcClient sender, User user)
        {
            var username = user.Username;

            if (cmbNickList.Items.Contains(username))
            {
                cmbNickList.Items.Remove(username);
            }
        }


    }
}